package yams.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import javafx.util.Callback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import yams.callback.IdCallback;
import yams.common.IRepository;
import yams.common.constants.BillStatusEnum;
import yams.common.constants.Constants;
import yams.common.exception.BreezeeException;
import yams.domain.*;
import yams.repository.IBillRepository;
import yams.repository.IContractRepository;
import yams.repository.IEnumRepository;
import yams.repository.IUserRepository;
import yams.service.IBillService;
import yams.service.IWeChatService;
import yams.utils.SystemTool;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.TreeMap;

/**
 * 账单服务
 * Created by Silence on 2017/5/2.
 */
@Service("billService")
public class DefaultBillService implements IBillService {

    @Resource
    private IWeChatService weChatService;

    @Autowired
    private IBillRepository billRepository;
    @Autowired
    private IUserRepository userRepository;
    @Autowired
    private IContractRepository contractRepository;
    @Autowired
    private IEnumRepository enumRepository;

    @Autowired
    private IdCallback idCallback;

    @Override
    public IRepository<BillEntity> getRepository() {
        return billRepository;
    }


    @Override
    public void generateBill(ContractEntity contract) throws BreezeeException {
        if (contract == null)
            throw new BreezeeException("不存在此合同信息");
        if (contract.getStatus() == 0)
            throw new BreezeeException("此合同已终止");

        HouseEntity house = contract.getHouse();
        UserEntity manager = userRepository.findOne(house.getManager());
        UserEntity user = contract.getUser();

        BigDecimal total = new BigDecimal(0);
        BillEntity billEntity = new BillEntity();
        billEntity.setStatus(0);
        billEntity.setType(1);
        billEntity.setContract(contract);
        billEntity.setUser(user);
        billEntity.setHouse(house);
        if (billEntity.getRentalAmount() == null)
            billEntity.setRentalAmount(new BigDecimal(contract.getRental()));
        total = total.add(billEntity.getRentalAmount());
        boolean updateContract = false;
        if (contract.getPayStatus() == null || contract.getPayStatus() != 1) {
            billEntity.setPledgeAmount(new BigDecimal(contract.getPledge()));
            total = total.add(billEntity.getPledgeAmount());
            contract.setPayStatus(1);
            updateContract = true;
        }
        billEntity.setTotalAmount(total);
        LocalDate ld = LocalDate.now();
        billEntity.setCode("1" + contract.getCode() + "-" + ld.toString().replace("-", ""));
        billEntity.setName(contract.getHouseName() + ld.toString() + "合同账单");
        if (billEntity.getDiscount() != null) {
            billEntity.setActualAmount(billEntity.getTotalAmount().multiply(billEntity.getDiscount()));
        } else {
            billEntity.setActualAmount(billEntity.getTotalAmount());
        }
        billRepository.saveEntity(billEntity, new Callback[]{idCallback});
        //更新押金状态
        if (updateContract)
            contractRepository.saveEntity(contract);

    }

    @Override
    public void payBill(BillEntity billEntity) throws BreezeeException {
        billRepository.saveEntity(billEntity);
    }

    /**
     * 合同管理功能中，手动生成账单，此功能一般不用，是特殊场景下使用，比如客户想提前看账单
     * @param billEntity
     * @param callback 回调函数
     * @return
     * @throws BreezeeException
     */
    @Override
    public BillEntity saveInfo(BillEntity billEntity, Callback<BillEntity, Object>[] callback) throws BreezeeException {
        ContractEntity contract = contractRepository.findOne(billEntity.getContract().getId());
        if (contract == null)
            throw new BreezeeException("不存在此合同信息");
        if (contract.getStatus() == 0)
            throw new BreezeeException("此合同已终止");
        BigDecimal total = new BigDecimal(0);
        billEntity.setUser(contract.getUser());
        billEntity.setHouse(contract.getHouse());

        if (billEntity.getType() == 1) {
            generateBill(contract);
        } else if (billEntity.getType() == 2) {
            LocalDate ld = LocalDate.now();
            billEntity.setCode("2" + contract.getCode() + "-" + ld.toString().replace("-", ""));
            billEntity.setName(contract.getHouseName() + ld.toString() + "水电气账单");
            //获取单价
            EnumEntity ee = enumRepository.findByCode("systemConfig");
            for (EnumItemEntity a : ee.getItems()) {
                if (a.getCode().equals("water")) {
                    billEntity.setWaterPrice(new BigDecimal(a.getName()));
                } else if (a.getCode().equals("electric")) {
                    billEntity.setElectricPrice(new BigDecimal(a.getName()));
                } else if (a.getCode().equals("gas")) {
                    billEntity.setGasPrice(new BigDecimal(a.getName()));
                }
            }
            if (billEntity.getWaterNum() != null) {
                billEntity.water();
                total = total.add(billEntity.getWaterAmount());
                contract.setWater(billEntity.getWaterNum().doubleValue());
            }
            if (billEntity.getElectricNum() != null) {
                billEntity.electric();
                total = total.add(billEntity.getElectricAmount());
                contract.setElectric(billEntity.getElectricNum().doubleValue());
            }
            if (billEntity.getGasNum() != null) {
                billEntity.gas();
                total = total.add(billEntity.getGasAmount());
                contract.setGas(billEntity.getGasNum().doubleValue());
            }
            if (billEntity.getOtherFee() != null)
                total = total.add(billEntity.getOtherFee());
            billEntity.setStatus(0);
            billEntity.setTotalAmount(total);
            if (billEntity.getDiscount() != null) {
                billEntity.setActualAmount(billEntity.getTotalAmount().multiply(billEntity.getDiscount()));
            } else {
                billEntity.setActualAmount(billEntity.getTotalAmount());
            }
            billRepository.saveEntity(billEntity, new Callback[]{idCallback});
            contractRepository.saveEntity(contract);
        } else if(billEntity.getType()==3){
            LocalDate ld = LocalDate.now();
            billEntity.setCode("3" + contract.getCode() + "-" + System.currentTimeMillis());
            billEntity.setName(contract.getHouseName() + ld.toString() + "其他费用账单");
            billEntity.setStatus(0);
            total = total.add(billEntity.getOtherFee());
            billEntity.setTotalAmount(total);
            if (billEntity.getDiscount() != null) {
                billEntity.setActualAmount(billEntity.getTotalAmount().multiply(billEntity.getDiscount()));
            } else {
                billEntity.setActualAmount(billEntity.getTotalAmount());
            }
            billRepository.saveEntity(billEntity, new Callback[]{idCallback});
        }
        //TODO 因为此功能一般不用，所以暂时没加微信消息发送功能
        return billEntity;
    }

    /**
     * 检查过期账单，并发送消息
     */
    @Override
    public void overdueBill(){

        BillEntity billCondition = new BillEntity();
        billCondition.getProperties().put("status", BillStatusEnum.UNPAID.getValue());
        billCondition.getProperties().put("createdDate_le",Date.from(LocalDateTime.now()
                                                           .atZone(ZoneId.systemDefault()).toInstant()));
        List<BillEntity> billList = listAll(billCondition);

        for(BillEntity bill : billList){
            BigDecimal amount = bill.getActualAmount();
            Date billDate = bill.getCreatedDate();
            Date nowDate = new Date();
            long diffDay = SystemTool.between(billDate,nowDate);

            UserEntity user = bill.getUser();
            UserEntity manager = userRepository.findOne(bill.getHouse().getManager());
            //给客户发送消息
            WechatTemplateMsg templateMsg = new WechatTemplateMsg();
            templateMsg.setTouser(user.getWeChat());
            templateMsg.setTemplate_id("nnkKtkWLzNysX-4M_Zwl5RY40zaRKy4Z1rdYUIFJguI");
            templateMsg.setUrl("http://"+ Constants.WECHAT_URL+"/yams/view/contract?openId="+user.getWeChat());
            TreeMap<String,TreeMap<String,String>> map = Maps.newTreeMap();
//            逾期客户：{{keyword1.DATA}}
//            逾期金额：{{keyword2.DATA}}
//            逾期天数：{{keyword3.DATA}}
            map.put("first", templateMsg.item("尊敬的客户，您好！您有逾期账单，请尽快处理","#173177"));
            map.put("keyword1", templateMsg.item(user.getName()+"("+user.getIdCard()+")","#173177"));
            map.put("keyword2", templateMsg.item(amount.toString()+"元","#173177"));
            map.put("keyword3", templateMsg.item(String.valueOf(diffDay)+"天","#173177"));
            map.put("remark", templateMsg.item("若有疑问请与管理员("+manager.getName()+","+manager.getPhone()+")联系","#173177"));
            templateMsg.setData(map);
            String jsonTempl = JSONObject.toJSONString(templateMsg);

            try {
                weChatService.sendTemplate(jsonTempl);
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }
}
